#!/usr/bin/python
# -*- coding: UTF-8 -*-
"""
Python 3.x

Python 类内置函数详解
"""

import sys


class User:
    """AI is creating summary for 
    """

    def __call__(self, *args, **kwds):
        """类对象后面加括号，触发执行。
        注：构造方法的执行是由创建对象触发的，即：对象 = 类名();
        而对于 __call__ 方法的执行是由对象后加括号触发的，即：对象() 或者 类()()
        """
        print(f"Current function name is : {sys._getframe().f_code.co_name}")
    # def __delattr__(self, __name: str) -> None:
    #     pass
    # def __dir__(self) -> Iterable[str]:
    #     pass
    # def __eq__(self, __o: object) -> bool:
    #     pass
    # def __format__(self, __format_spec: str) -> str:
    #     pass
    # def __getattribute__(self, __name: str) -> Any:
    #     pass
    # def __hash__(self) -> int:
    #     pass

    def __init__(self, user_name, real_name) -> None:
        """init是实例方法，执行实例初始化，在new返回的对象中执行。
        """
        self.user_name = user_name
        self.real_name = real_name
        print(f"Current function name is : {sys._getframe().f_code.co_name}")

    # def __init_subclass__(cls) -> None:
    #     pass
    # def __instancecheck__(self, __instance: Any) -> bool:
    #     pass
    # def __ne__(self, __o: object) -> bool:
    #     pass
    def __new__(cls, user_name, real_name):
        """new是静态（@staticmethod）方法，用于创建实例对象，方法必须返回一个对象;
        可以通过重写__new方法来实现单例模式
        instance = None
        def __new__(cls):
            if not cls.instance:
                cls.instance = object.__new__(cls)
            return cls.instance
        """
        print(f"Current function name is : {sys._getframe().f_code.co_name}")
        return object.__new__(cls)
    # def __reduce__(self) -> str | tuple[Any, ...]:
    #     pass
    # def __reduce_ex__(self, __protocol: SupportsIndex) -> str | tuple[Any, ...]:
    #     pass
    # def __repr__(self) -> str:
    #     pass
    # def __setattr__(self, __name: str, __value: Any) -> None:
    #     pass
    # def __sizeof__(self) -> int:
    #     pass

    def __str__(self) -> str:
        """打印对象时, 默认输出该方法的返回值; 
        print(obj), str(obj)方法调用对象时,都会调用__str__方法。
        Returns:
            str: _description_
        """
        print(f"Current function name is : {sys._getframe().f_code.co_name}")
        return ""
    # def __subclasses__(self: Self) -> list[Self]:
    #     pass
    # def __subclasscheck__(self, __subclass: type) -> bool:
    #     pass

    def __getitem__(self, item):
        print(f"Current function name is : {sys._getframe().f_code.co_name}")

    def __setitem__(self, key, value):
        print(f"Current function name is : {sys._getframe().f_code.co_name}")

    def __delitem__(self, key):
        print(f"Current function name is : {sys._getframe().f_code.co_name}")

    def upload_img(self):
        print(f"Upload user image.")
    
    def __enter__(self):
        print(f"Current function name is : {sys._getframe().f_code.co_name}")
        return self

    def __exit__(self):
        print(f"Current function name is : {sys._getframe().f_code.co_name}")

if __name__ == '__main__':
    obj = User("user", "user")  # 执行 __new__和__init__
    obj()                       # 执行 __call__
    print(obj)                  # 执行 __str__
    obj['k1']                   # 执行 __getitem__
    obj['k1'] = 1               # 执行 __setitem__
    del obj['k1']               # 执行 __delitem__
    with User as w_user:
        w_user.upload_img()

    print("-"*40)
    print(f"class.__module__ :         {obj.__module__}")      # 输出类所属模块
    print(f"class.__class__  :         {obj.__class__}")       # 输出类
    print(f"class.__dict__   :         {obj.__dict__}")        # 输出类或对象中的所有成员
    print(f"class.__doc__    :         {obj.__doc__}")         # 输出类描述信息
